package xyz.hlh.argumentResolvers;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import xyz.hlh.annotition.LoginUser;
import xyz.hlh.common.Constant;
import xyz.hlh.entity.User;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description 登录参数注入，通过spring参数解析器解析
 * @author HLH
 * @email 17703595860@163.com
 * @date Created in 2021/8/1 下午9:35
 */
@Component
public class LoginUserResolver implements HandlerMethodArgumentResolver {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 是否进行拦截
     * @param parameter 参数对象
     * @return true，拦截。false，不拦截
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(LoginUser.class);
    }

    /**
     * 拦截之后执行的方法
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        // 从request中获取token，此处只做参数解析，不做登录校验
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return null;
        }
        HttpServletRequest request = requestAttributes.getRequest();
        // 获取token
        String token = request.getHeader(Constant.TOKEN_HEADER_NAME);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        // 从redis中拿token对应user
        return (User) redisTemplate.opsForValue().get(Constant.REDIS_USER_PREFIX + token);
    }
}
